package mysgoog.pattern;

import java.util.*;

import mysgoog.board.*;
import mysgoog.gtp.*;
import mysgoog.pattern.StartGame.*;
import mysgoog.pattern.Storage.VertexValue;
import mysgoog.pattern.attack.AttackPatternMatcher;
import mysgoog.pattern.defense.DefensePatternMatcher;
import mysgoog.pattern.endgamePattern.*;
import mysgoog.pattern.eyesPattern.EyesPatternMatcher;
import mysgoog.pattern.eyesPattern.MakeeyePatternMatcher;
import mysgoog.pattern.influence.*;
import mysgoog.pattern.smallPattern.SmallPatternMatcher;

/**
 * @author Fu, Zhongyang
 */
public class PatternMatcher
{
    StartGamePatternMatcher startGame = null;
    EndGamePatternMatcher endGame = null;
    InfluencePatternMatcher influence = null;
    DefensePatternMatcher defense = null;
    AttackPatternMatcher attack = null;
    SmallPatternMatcher small = null;
    EyesPatternMatcher eyes = null;
    MakeeyePatternMatcher makeeye = null;

    public PatternMatcher()
    {
        startGame = new StartGamePatternMatcher();
        influence = new InfluencePatternMatcher();
        endGame = new EndGamePatternMatcher();
        defense = new DefensePatternMatcher();
        attack = new AttackPatternMatcher();
        eyes = new EyesPatternMatcher();        
        small = new SmallPatternMatcher();
        makeeye = new MakeeyePatternMatcher();
    }
    
    public List<VertexValue> getMatch(Board board, Color player)
    {
        List<VertexValue> moves = new ArrayList<VertexValue>();
        startGame.getMatch(board, player, moves);
        influence.getMatch(board, player, moves);
        moves = clearup(moves);
        return moves;
    }
    public List<VertexValue> getMakeeyePatternMatch(Board board, Color player)
    {
        List<VertexValue> moves = new ArrayList<VertexValue>();
        makeeye.getMatch(board, player, moves);
        moves = clearup(moves);
        return moves;
    }
    public List<VertexValue> getEyesPatternMatch(Board board, Color player)
    {
        List<VertexValue> moves = new ArrayList<VertexValue>();
        eyes.getMatch(board, player, moves);
        moves = clearup(moves);
        return moves;
    }
    public List<VertexValue> getAttackPatternMatch(Board board, Color player)
    {
        List<VertexValue> moves = new ArrayList<VertexValue>();
        attack.getMatch(board, player, moves);
        moves = clearup(moves);
        return moves;
    }
    public List<VertexValue> getDefensePatternMatch(Board board, Color player)
    {
        List<VertexValue> moves = new ArrayList<VertexValue>();
        defense.getMatch(board, player, moves);
        moves = clearup(moves);
        return moves;
    }
    public List<VertexValue> getEndGamePatternMatch(Board board, Color player)
    {
        List<VertexValue> moves = new ArrayList<VertexValue>();
        defense.getMatch(board, player, moves);
        endGame.getMatch(board, player, moves);
        makeeye.getMatch(board, player, moves);
        moves = clearup(moves);
        return moves;
    }
    public List<VertexValue> getStartGamePatternMatch(Board board, Color player)
    {
        List<VertexValue> moves = new ArrayList<VertexValue>();
        startGame.getMatch(board, player, moves);
        influence.getMatch(board, player, moves);	
        moves = clearup(moves);
        return moves;
    }
    public List<VertexValue> getSmallPatternMatch(Board board, Color player)
    {
        List<VertexValue> moves = new ArrayList<VertexValue>();
        attack.getMatch(board, player, moves); 
        small.getMatch(board, player, moves);
        moves = clearup(moves);
        return moves;
    }
    private	 List<VertexValue> clearup(List<VertexValue> moves)
    {
        sort(moves);
        return removeDuplicate(moves);
    }
    private List<VertexValue> removeDuplicate(List<VertexValue> moves)
    {
        List<VertexValue> newList = new ArrayList<VertexValue>();
        VertexValue lastMove = null;
        for (VertexValue move : moves)
        {
            if (lastMove == null)
                newList.add(move);
            else
            {
                if (!lastMove.equals(move))
                    newList.add(move);
            }
            lastMove = move;
        }
        return newList;
    }
    private void sort(List<VertexValue> moves)
    {
        Collections.sort(moves, new VertexValueComparator());
    }

    private class VertexValueComparator implements Comparator<VertexValue>
    {
        @Override
        public int compare(VertexValue arg0, VertexValue arg1)
        {
            if (arg0.value > arg1.value)
                return -1;
            if (arg0.value == arg1.value)
            {
                if (arg0.vertex.x > arg1.vertex.x)
                    return -1;
                else if (arg0.vertex.x < arg1.vertex.x)
                    return 1;
                else if (arg0.vertex.y > arg1.vertex.y)
                    return -1;
                else if (arg0.vertex.y < arg1.vertex.y)
                    return 1;
                return 0;
            }
            return 1;
        }
    }
}
